home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Gamers Delight 2
/
Gamers Delight 2.iso
/
Aminet
/
game
/
role
/
Infocom64ToDat.lha
/
Dsk2Infocom.c
< prev
next >
Wrap
C/C++ Source or Header
|
1993-08-31
|
6KB
|
236 lines
/****************************************************************/
/* "dsk2infocom" converts disk image of Infocom game */
/* for the Commodore 64 to a data file which can be */
/* used on every computer */
/* */
/* v1.0: April 26, 1993 */
/* v1.0a: May 24, 1993 */
/* */
/* Author: Paul David Doherty (h0142kdd@rz.hu-berlin.de) */
/****************************************************************/
#include <stdio.h>
#include <stdlib.h>
#define TRUE 1
#define FALSE 0
#define MAXLENGTH 131072 /* longest possible V3 datafile */
/*
C-64, using tracks 5-16 and 18-35 -> 30 * 17 * 256 = 130560
Apple II, using tracks 4-35 -> 32 * 16 * 256 = 131072
*/
struct ids
{
char *version;
char type;
unsigned short id[6];
} vers_ids[] =
{
"A1", 1, 0xf5, 0x60, 0x20, 0xf7, 0x1f, 0x20,
"A2", 1, 0x00, 0xd0, 0xf5, 0x60, 0x20, 0xf9,
/*
"A1" and "A2" are version names I just made up...
*/
"B", 2, 0x0f, 0xa8, 0xa6, 0x78, 0x20, 0xba,
"C", 3, 0xff, 0xa2, 0x0f, 0x20, 0xc9, 0xff,
"D", 3, 0xdd, 0x27, 0x09, 0x30, 0x99, 0xf0,
"E", 3, 0xff, 0xa2, 0x00, 0xc9, 0x0a, 0x90,
"F", 3, 0xa2, 0xef, 0xa0, 0x27, 0xa9, 0x01,
"G", 3, 0x69, 0x6e, 0x75, 0x65, 0x2e, 0x0d,
"H", 3, 0x45, 0x54, 0x55, 0x52, 0x4e, 0x5d,
"Unknown", 0, 0, 0, 0, 0, 0, 0
};
struct specs
{
char t4; /* track 4 used? */
/*
tracks 5..16 are always used
*/
char t17; /* track 17 used? */
char t18; /* track 18 used? [starts at sec 2] */
/*
tracks 19..35 are always used
*/
char tr_used; /* 16 = 0..15, 17 = 0..16 */
} vers_specs[] =
{
0, 0, 0, 0, /* 0 - don't leave it out! */
TRUE, TRUE, TRUE, 16, /* 1 */
FALSE, FALSE, FALSE, 16, /* 2 */
FALSE, FALSE, TRUE, 17 /* 3 */
};
FILE *infile;
FILE *outfile;
char version;
unsigned short checksum;
unsigned short checkedsum = 0;
unsigned long bytecount = 0;
unsigned long filelength;
void gotrack (int);
void transtrack (void);
void usage (void);
/*******************************************************************/
/* MAIN function */
/*******************************************************************/
void
main (int argc, char **argv)
{
int i, j;
char gv;
char dummy[30];
unsigned short act_id[6];
if (--argc != 1)
usage ();
if ((infile = fopen (argv[argc], "rb")) == NULL)
{
printf ("Error: Can't read \"%s\"\n", argv[argc]);
exit (5);
}
strcpy (dummy, argv[argc]);
strcat (dummy, ".dat");
if ((outfile = fopen (dummy, "wb")) == NULL)
{
printf ("Error: Can't create \"%s\"\n", dummy);
exit (5);
}
fseek (infile, 0x2000, SEEK_SET);
for (i = 0; i < 6; i++)
act_id[i] = getc (infile);
i = 0;
do
{
gv = version = vers_ids[i].type;
for (j = 0; j < 6; j++)
{
if (act_id[j] != vers_ids[i].id[j])
version = 0;
}
i++;
}
while ((gv != 0) && (version == 0));
if (version == 0)
{
printf ("%s interpreter\n", vers_ids[--i].version);
exit (5);
}
printf ("C-64 Interpreter %s\n", vers_ids[--i].version);
for (i = 4; i <= 35; i++)
{
if ((i == 4) && (!(vers_specs[version].t4)))
continue;
if ((i == 17) && (!(vers_specs[version].t17)))
continue;
if ((i == 18) && (!(vers_specs[version].t18)))
continue;
gotrack (i);
if (i == 18)
fseek (infile, 512, SEEK_CUR);
transtrack ();
}
}
/*******************************************************************/
/* Function: gotrack */
/*******************************************************************/
void
gotrack (int track)
{
unsigned long pos;
/*
track 1..17: 21 sectors
18..24: 19
25..30: 18
31..35: 17
*/
pos = (track - 1) * 21;
pos = pos - ((track > 18) ? (track - 18) : 0) * 2;
pos = pos - ((track > 25) ? (track - 25) : 0) * 1;
pos = pos - ((track > 31) ? (track - 31) : 0) * 1;
fseek (infile, pos * 256, SEEK_SET);
}
/*******************************************************************/
/* Function: transtrack */
/*******************************************************************/
void
transtrack (void)
{
int gotten;
int j, k;
for (j = 0; j < (vers_specs[version].tr_used); j++)
{
for (k = 0; k < 256; k++)
{
gotten = getc (infile);
putc (gotten, outfile);
if (bytecount == 0x1a)
filelength = gotten * 256;
if (bytecount == 0x1b)
{
filelength = (filelength + gotten) * 2;
if (filelength == 0)
filelength = MAXLENGTH;
}
if (bytecount == 0x1c)
checksum = gotten * 256;
if (bytecount == 0x1d)
checksum = checksum + gotten;
bytecount++;
if (bytecount > 0x40)
{
checkedsum = checkedsum + gotten;
if (bytecount == filelength)
{
printf ("Checksum %s\n", (checksum == checkedsum) ? "okay" : "incorrect!");
exit (0);
}
}
}
}
}
/*******************************************************************/
/* Function: usage */
/*******************************************************************/
void
usage (void)
{
printf ("\nDsk To Infocom V1.0\n");
printf ("\n");
printf ("Usage: Dsk2Infocom Filename.\n\n");
exit (0);
}